/**************************************************************************************************
* Title: SumResourceManager.cpp
* Author: Gael Huber
* Description: Manages all renderable resources used for engine.
**************************************************************************************************/
#include "SumResourceManager.h"

/**************************************************************************************************
* Initialize singleton to 0
**************************************************************************************************/
template <> ResourceManager* Singleton<ResourceManager>::singleton = 0;

/**************************************************************************************************
* Default constructor
**************************************************************************************************/
ResourceManager::ResourceManager(void)
{ }

/**************************************************************************************************
* Destructor
**************************************************************************************************/
ResourceManager::~ResourceManager(void)
{ }

/**************************************************************************************************
* Initialize resource manager
**************************************************************************************************/
void ResourceManager::startUp(void) {
	// Initialize resource groups
	_initializeResourceGroups();
}

/**************************************************************************************************
* Shut down resource manager and ensure all resources are properly released from memory
**************************************************************************************************/
void ResourceManager::shutDown(void) {
	// TODO
}

/**************************************************************************************************
* Initialize resource groups. This will read in resource config file and parse all related
* directories for files. Each resource type will be initialized as per its own manager.
**************************************************************************************************/
void ResourceManager::_initializeResourceGroups(void) {
	// Read in resource configuration file and parse
	fstream stream("..//config//resources.cfg");

	// Pre-allocate for line data
	char cLine[256];
	String line(256);

	// Read in stream
	while(!stream.eof()) {
		// Line data
		ReadLine(stream, cLine, line);
	
		// Read the line
		if(line.at(0) == '#') {
			// IGNORE
		} else if(line.find('[') != -1) {
			// Construct a group
			// ------------------

			// Create group name
			String groupName = line.substring(++line.begin(), --line.end());
			
			// Compile directories to be searched
			List<String> directories;

			// Read a line
			ReadLine(stream, cLine, line);
			
			// Search for blank lines
			while(line.getLength() > 0) {
				// Parse line
				int pos = line.find('=');
				String type = line.substring(line.begin(), String::Iterator(&line.at(pos)));
				String directory = line.substring(++String::Iterator(&line.at(pos)), line.end());

				if(type == "Directory") {
					directories.push_back(directory);
				}

				// Get the next line
				ReadLine(stream, cLine, line);
			}

			// Create group
			MeshManager* meshManager = new MeshManager();
			meshManager->initializeResourceGroup(groupName, directories);
		}
	}
}

/**************************************************************************************************
* Create a render entity
**************************************************************************************************/
RenderEntity ResourceManager::createRenderEntity(const String& entName, const String& meshName) {
	// Is this a valid entity
	if(entName == "") {
		return RenderEntity(entName, 0);
	}

	// Fetch constituent components
	return RenderEntity(
		entName,
		requestMesh(meshName)
		);
}

/**************************************************************************************************
* Request a mesh
**************************************************************************************************/
Mesh* ResourceManager::requestMesh(const String& meshName) {
	return MeshManager::getSingletonPtr()->retrieveMesh(meshName);
}
